uniapp 网络请求封装 + token刷新 您所在的位置:网站首页 uniapp 刷新 uniapp 网络请求封装 + token刷新

uniapp 网络请求封装 + token刷新

2023-03-14 02:58| 来源: 网络整理| 查看: 265

大家好😊,我叫天黑黑,默默在掘金潜水很长时间了,今天刚刚提测了小程序,下午在掘金划划水(嘘...),突发奇想,想写一篇热乎的文章(第一次写文章...😋)

前两周被通知要做一个钉钉小程序,由于公司的技术栈是vue,就选择了uni-app 作为小程序的前端框架

项目目录

image.png

... ├──src │   ├──api               // api文件夹 │   ├──modules            // 分模块的请求地址 │   ...          │   ├──index.js           // modules的整合 │   ├──request.js         // 请求封装 | ... │   ├──config             // 根据不同环境配置的请求地址 .... 复制代码

项目中按模块划分了请求,只要在 modules 文件夹中新增模块的请求js文件(例如:登录模块:新增 modules/login.js )

在 api/index.js 对 modules 进行统一整合。

api/inedx.js const modulesFiles = require.context('./modules', true, /\.js$/) const modules = modulesFiles.keys().reduce((modules, modulePath) => { const value = modulesFiles(modulePath) modules = { ...modules, ...value.default } return modules }, {}) export default { ...modules } 复制代码

使用webpack中的 require.context 获取上下文,不用写过多的import来导入模块

例:base.js /** * 请求配置项:默认值 * url = '', * method = 'GET', * BASE_API = env_config.BASE_API, * headers = {'Content-Type': 'application/x-www-form-urlencoded'}, // 默认 * dataType = 'json', // 支持json、text、base64 * timeout = 30000 // 默认 30000 * loading = true, * loadingText = '加载中...', * token = true **/ import HTTP from '../request.js'; const BASE_API = { // 获取token API_TOKEN() { return HTTP({ url: `/api/auth/token`, token: false, loading: false }) }, // 获取用户信息 API_USER_INFO(data) { return HTTP({ url: '/api/auth/userinfo', loading: false }, data) } } export default BASE_API 复制代码 config/

config文件夹,是通过 process.env.NODE_ENV 来配置不同环境的全局变量,例如 BaseURL、小程序ID等...

api/request.js

这是对 dd.httpRequest 的二次封装,如下:

const env_config = require('../config/index.js') import store from '../store/index.js' let isRefresh = false // 是否在请求新的token const http = (option, data) => { let { url = '', method = 'GET', BASE_API = env_config.BASE_API, headers = {'Content-Type': 'application/x-www-form-urlencoded'}, // 默认 dataType = 'json', // 支持json、text、base64 timeout = 3000000, // 默认 30000 loading = true, loadingText = '加载中...', token = true } = option // 1.2 Promise return new Promise(async (resolve, reject) => { // 是否需要 请求loading if(loading) { dd.showLoading({ content: loadingText, }); } // 是否需要token if(token) { let access_token = dd.getStorageSync({ key: 'access_token' }).data if(!access_token) { // 具体获取token的请求,在store中 await store.dispatch('getAccessToken').then(res => { access_token = res.token }) } headers = { ...headers, "Authorization": `Bearer ${access_token}` } } method = method.toUpperCase(); dd.httpRequest({ url: BASE_API + url, method: method, headers: headers, data: data, timeout: timeout, dataType: dataType, success: function(res) { if(res.status === 200) { resolve(res.data) } else { dd.showToast({ type: 'fail', content: res.data.msg, duration: 3000 }); } }, fail: async function(res) { // 如果接口返回 401 无权限,再请求一次token,并在resolve中返回本次请求 if(res.status === 401) { if(!isRefresh) { isRefresh = true await store.dispatch('getAccessToken').then(res => { if(res.code === '0') { resolve(http(option, data)) } else { dd.showToast({ type: 'fail', content: res.msg, duration: 3000, success:() => { dd.navigateTo({ url: '/pages/noToken' }) } }); } }).catch(err => { dd.showToast({ type: 'fail', content: err.msg, duration: 3000, success:() => { dd.navigateTo({ url: '/pages/noToken' }) } }); }).finally(() => { isRefresh = false }) } } else { reject(res) } }, complete: function(res) { dd.hideLoading(); } }); }) }; export default http 复制代码

这里用的钉钉小程序的api,可以换成uniapp的api,同样适用;

在main.js中:

import http from './api/index.js'; Vue.prototype.$HTTP = http 复制代码 如何使用

在项目中使用如下:

const data = { userId: 'test' } this.$HTTP.API_USER_INFO(data).then(res => { ... }).catch(() => { ... }).finally(() => { ... }) 复制代码


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有